//
//  NSObject+BBKvo.m
//  自定义KVO
//
//  Created by 崔博 on 2017/12/25.
//  Copyright © 2017年 崔博. All rights reserved.
//

#import "NSObject+BBKvo.h"
#import <objc/message.h>
@implementation NSObject (BBKvo)
//
- (void)bb_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{
    // self 是Person 被观察者
    // observer --》观察者
    /*
        1.自定义子类对象
        2.重写set方法 在方法中，调用super的，通知观察者！
        3.修改当前对象的isa指针！！指向自定义的子类
     */
    // 1.动态生成一个类
    // 1.1 获取类名
    NSString * oldClassName = NSStringFromClass([self class]);
    NSString * newClassName = [@"BBKVO_" stringByAppendingString:oldClassName];
    const char * newName = [newClassName UTF8String];
    
    // 创建一个类的class
    Class MyClass = objc_allocateClassPair([self class] , newName, 0);
    objc_registerClassPair(MyClass);
    
    // 2.添加set方法
    class_addMethod(MyClass, @selector(setName:), (IMP)setName, "V@:@");
    
    // 3.修改isa指针
    object_setClass(self, MyClass);
    
    // 4.保存观察者对象
    objc_setAssociatedObject(self, @"objc", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// 调用super set方法
// 通知外界！
void setName(id self,SEL _cmd, NSString * newName){
    // 调用父类set的方法
    id class = [self class];
    // 改变selfid的isa指针
    object_setClass(self, class_getSuperclass(class));
    // 调用父类的set方法
    objc_msgSend(self, @selector(setName:),newName);
    NSLog(@"修改完毕");
    
    // 通知观察者
    id objc = objc_getAssociatedObject(self, @"objc");
    
    // 通知观察者
    objc_msgSend(objc,@selector(observeValueForKeyPath:ofObject:change:context:),self,@"name",nil,nil);
    
    // 改回子类类型
    
}
@end
